package com.ouyunc.oauth2.config.override;

import com.alibaba.fastjson.JSONObject;
import com.ouyunc.oauth2.feign.UserClient;
import com.ouyunc.service.dto.OauthClientDetailsDTO;
import com.ouyunc.common.base.ResponseResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;

import java.util.Arrays;

/**
 * 自定义jdbc clientDetail 的操作类加上缓存，提高效率
 */
public class IJdbcClientDetailsService implements ClientDetailsService {
    /**
     * redis 缓存模板
     */
    private RedisTemplate<String, Object> redisTemplate;
    /**
     * 用户服务客户端
     */
    private UserClient userClient;
    /**
     * 保存本地线程中的数据信息
     */
    public static final ThreadLocal<BaseClientDetails> threadLocal = new ThreadLocal<>();

    public IJdbcClientDetailsService(RedisTemplate<String, Object> redisTemplate, UserClient userClient) {
        this.redisTemplate = redisTemplate;
        this.userClient = userClient;
    }

    @Override
    public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
        // 使用缓存来进行优化
        BaseClientDetails BaseClientDetails = threadLocal.get();
        // 如果为null 需要查数据库，并更新到缓存中
        if (BaseClientDetails != null) {
           return BaseClientDetails;
        }
        OauthClientDetailsDTO oauthClientDetails = null;
        // 在过滤器中调用feign,全局异常处理不了，这里需要自行处理
        ResponseResult<OauthClientDetailsDTO> response = userClient.loadClientByClientId(clientId);
        // 判断是否请求成功
        if (response.isSuccess()) {
            oauthClientDetails = response.getData();
        }
        BaseClientDetails baseClientDetails = new BaseClientDetails(oauthClientDetails.getClientId(), oauthClientDetails.getResourceIds(), oauthClientDetails.getScope(), oauthClientDetails.getAuthorizedGrantTypes(),oauthClientDetails.getAuthorities(), oauthClientDetails.getWebServerRedirectUri());
        baseClientDetails.setClientSecret(oauthClientDetails.getClientSecret());
        baseClientDetails.setAccessTokenValiditySeconds(oauthClientDetails.getAccessTokenValidity());
        baseClientDetails.setRefreshTokenValiditySeconds(oauthClientDetails.getRefreshTokenValidity());
        String additionalInformation = oauthClientDetails.getAdditionalInformation();
        if (StringUtils.isNotBlank(additionalInformation)) {
            baseClientDetails.setAdditionalInformation(JSONObject.parseObject(additionalInformation));
        }
        String autoapprove = oauthClientDetails.getAutoapprove();
        if (StringUtils.isNotBlank(autoapprove)) {
            baseClientDetails.setAutoApproveScopes(Arrays.asList(autoapprove.split(",")));
        }
        threadLocal.set(baseClientDetails);
        return baseClientDetails;
    }

}
